#include "EndRecvReqHandler.h"
#include "BeforeConnOriDispatcher.h"
#include "GlobalContext.h"
#include "ConnectReqHandler.h"
#include "NotifyProc.h"

using namespace std;
using namespace log4cplus;

Logger EndRecvReqHandler::log=GetLogger(LOG4CPLUS_TEXT("EndRecvReqHandler"));

ITransHandler::ExecuteResultCode EndRecvReqHandler::Execute(ClientContext &client,OVERLAPPED *ovl)
{
	unsigned int clienSequenceNo=client.SequenceNo();
	ExecuteResultCode ret=ITransHandler::ExecuteOK;
	DWORD recvCount=0;
	DWORD flags;
	BOOL result=::WSAGetOverlappedResult(client.SrcSock(),client.OVL(),&recvCount,true,&flags);
	int errCode=::WSAGetLastError();
	if(result)
	{
		if(recvCount==0)
		{
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]Receive 0 byte data,exit."),clienSequenceNo);
			return ITransHandler::ExecuteFinished;
		}
		LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]EndRecvReqHandler receive request partital data successed,start to parse."),clienSequenceNo);
		char *first=client.Buffer()->buf;
		char *last=first+recvCount;
		client.HttpRequest().AppendData(first,last);
		if(client.HttpRequest().IsValid())
		{
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]EndRecvReqHandler receive all request successed."),clienSequenceNo);
			client.HttpRequest().InitializeRequestRange(client.TranslatedFileIndex(),client.MaxFileIndex());
			if(client.HttpRequest().Type()=="CONNECT")
			{
				delete client.SetCurrentHandler(new ConnectReqHandler());
			}
			else
			{
				delete client.SetCurrentHandler(new BeforeConnOriDispatcher());
			}
			NotifyProc(NOTIFY_REQUEST_RECEIVED,client.HttpRequest().FullRequestUrl().c_str());
			::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),0,static_cast<ULONG_PTR>(client.SequenceNo()),NULL);
		}
		else
		{
			LOG4CPLUS_DEBUG_FMT(log,LOG4CPLUS_TEXT("[Client%d]EndRecvReqHandler receive data is partital data,retry."),clienSequenceNo);
			DWORD flags=0;
			ZeroMemory(client.OVL(),sizeof(OVERLAPPED));
			int recvResult = ::WSARecv(client.SrcSock(),client.Buffer(),1,NULL,&flags,client.OVL(),NULL);
			errCode=::WSAGetLastError();
			if(recvResult!=0&&errCode!=WSA_IO_PENDING)
			{
				ret=ITransHandler::ExecuteFatalError;
				LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]EndRecvReqHandler begin receive data failed,error code:%d."),clienSequenceNo,errCode);
			}
		}
	}
	else
	{
		ret=ITransHandler::ExecuteFatalError;
		LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]EndRecvReqHandler end receive request data failed,error code:%d."),clienSequenceNo,errCode);
	}
	return ret;
}